package com.gxy.learn.backup.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.Setter;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@ConfigurationProperties(prefix = "spring.datasource.second")
@MapperScan(basePackages = {"com.gxy.learn.bd.mapper.second"}, sqlSessionFactoryRef = "sqlSessionFactorySecond")
public class SecondDataSourceConfig {
    @Setter
    private String url;
    @Setter
    private String driverClassName;
    @Setter
    private String username;
    @Setter
    private String password;
    @Setter
    private Integer initialSize;
    @Setter
    private Integer minIdle;
    @Setter
    private Integer maxActive;
    @Setter
    private Integer maxWait;
    @Setter
    private String validationQuery;
    @Setter
    private Integer validationQueryTimeout;
    @Setter
    private Long timeBetweenEvictionRunsMillis;
    @Setter
    private Long minEvictableIdleTimeMillis;
    @Setter
    private Integer maxWaithThreadCount;
    @Setter
    private Integer removeAbandonedTimeout;
    @Setter
    private Boolean testOnBorrow;
    @Setter
    private Boolean testOnReturn;

    @Bean(name = "dataSourceSecond")
    public DataSource dataSource() {
        /**
         * initialSize	池启动时创建的连接数量
         * maxActive	同一时间可以从池分配的最多连接数量。设置为0时表示无限制。
         * maxIdle	池里不会被释放的最多空闲连接数量。设置为0时表示无限制。
         * maxOpenPreparedStatements	同一时间能够从语句池里分配的已备语句的最大数量。设置为0时表示无限制。
         * maxWait	在抛出异常之前，池等待连接被回收的最长时间（当没有可用连接时）。设置为-1表示无限等待。
         * minEvictableIdleTimeMillis	连接保持空闲而不被驱逐的最长时间。
         * minIdle	在不新建连接的条件下，池中保持空闲的最少连接数。
         * poolPreparedStatements	是否对已备语句进行池管理（布尔值）。
         * validationQuery 用来验证数据库连接的语句
         * validationQueryTimeout
         * 间隔多久进行检测需要关闭的空闲连接
         * timeBetweenEvictionRunsMillis
         * 配置连接在池中最小生存的时间
         * minEvictableIdleTimeMillis
         * 最大等待线程数
         * maxWaithThreadCount
         * 如果为true（默认false），当应用向连接池申请连接时，连接池会判断这条连接是否是可用的。
         * testOnBorrow
         * 如果为true（默认false），当应用使用完连接，连接池回收连接的时候会判断该连接是否还可用。
         * testOnReturn
         * 如果为true（默认true），当应用向连接池申请连接，并且testOnBorrow为false时，连接池将会判断连接是否处于空闲状态，如果是，则验证这条连接是否可用。
         * testWhileIdle
         */
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setValidationQueryTimeout(validationQueryTimeout);
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        dataSource.setTimeBetweenConnectErrorMillis(timeBetweenEvictionRunsMillis);
        dataSource.setMaxWaitThreadCount(maxWaithThreadCount);
        dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestOnReturn(testOnReturn);
//        dataSource.setTestWhileIdle();

        return dataSource;
    }

    @Bean(name = "sqlSessionFactorySecond")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSourceSecond") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/second/*.xml"));
        org.apache.ibatis.session.Configuration configuration=new org.apache.ibatis.session.Configuration();
//        使用jdbc的getGeneratedKeys获取数据库自增主键值
        configuration.setUseGeneratedKeys(true);
//        使用列别名替换列名，如：select user as User
        configuration.setUseColumnLabel(true);
//        -自动使用驼峰命名属性映射字段，如userId    user_id
        configuration.setMapUnderscoreToCamelCase(true);
        bean.setConfiguration(configuration);
        return bean.getObject();
    }

    @Bean(name = "transactionManagerSecond")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSourceSecond") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    @Bean(name = "sqlSessionTemplateSecond")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactorySecond") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
